package com.duan.laugh.event.listener;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.duan.laugh.common.event.constants.EventConstant;
import com.duan.laugh.common.event.pojo.dto.EventDTO;
import com.duan.laugh.event.pojo.entity.EventHandler;
import com.duan.laugh.event.pojo.entity.EventModel;
import com.duan.laugh.event.service.IEventHandlerService;
import com.duan.laugh.event.service.IEventModelService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 队列消息监听
 *
 * @author duanjw
 */
@Component
@Slf4j
@AllArgsConstructor
public class EventReceiveListener {

    @Autowired
    private IEventModelService eventModelService;
    @Autowired
    private IEventHandlerService eventHandlerService;


    /**
     * 监听事件队列消息
     *
     * @param eventDTO
     */
    @RabbitListener(queues = EventConstant.MQ_QUEUE_EVENT)
    public void receive(EventDTO eventDTO) {
        List<EventModel> eventModels = null;
        Map<String, String> eventData = eventDTO.getEventData();
        long startTime = System.currentTimeMillis();
        log.info("监听事件队列消息，收到消息【{}】", eventDTO);
        long useTime = System.currentTimeMillis() - startTime;
        log.info("耗时【{}】毫秒", useTime);
        String url = eventData.getOrDefault(EventConstant.REQUEST_PATH, null);
        log.info("监听事件队列消息，url【{}】", url);
        String method = eventData.get(EventConstant.REQUEST_METHOD);
        log.info("监听事件队列消息，method【{}】", method);
        String requestParam = eventData.get(EventConstant.REQUEST_PARAM);
        log.info("监听事件队列消息，requestParam【{}】", requestParam);
        String requestBody = eventData.get(EventConstant.REQUEST_BODY);
        log.info("监听事件队列消息，requestBody【{}】", requestBody);
        // 合并参数
        String pramsJsonString = null;
        // 事件类型
        Integer type = eventDTO.getType();
        // 如果是后续事件
        if (EventConstant.EVENT_TYPE_ID.equals(type)) {
            // 拿到事件模型id
            String eventModelId = eventData.get("eventModelId");
            pramsJsonString = eventData.get("params");
            EventModel eventModel = eventModelService.getById(eventModelId);
            eventModels = new ArrayList<>(1);
            eventModels.add(eventModel);
        } else {
            // 匹配事件模型
            eventModels = eventModelService.selectEventByUrlAndMethod(url, method);
            pramsJsonString = uniteParam(requestParam, requestBody);
        }
        EventHandler eventHandler = null;
        EventModel eventModel = null;
        for (int i = 0, n = eventModels.size(); i < n; i++) {
            eventModel = eventModels.get(i);
            // 生成事件处理
            eventHandler = new EventHandler()
                    .setEventModelId(eventModel.getId())
                    .setName(eventModel.getName())
                    .setTenantId(eventModel.getTenantId())
                    .setType(eventModel.getType())
                    .setParams(pramsJsonString)
                    .setUrl(url)
                    .setCreateTime(LocalDateTime.now());
            eventHandlerService.insertEventHandler(eventHandler);
            log.info("已生成事件处理,详细内容：{}", eventHandler);
        }

    }

    /**
     * requestParam、requestBody 参数合并
     *
     * @param requestParam
     * @param requestBody
     * @return
     */
    private String uniteParam(String requestParam, String requestBody) {
        JSONObject requestBodyJson = null;
        JSONObject requestParamJson = null;
        JSONObject pramsJson = new JSONObject();
        if (StrUtil.isNotBlank(requestParam)) {
            // url 参数转 jsonObject
            requestParamJson = this.getJsonObjectByQueryUrl(requestParam);
        }
        if (StrUtil.isNotBlank(requestBody)) {
            requestBodyJson = JSON.parseObject(requestBody);
        }
        if (requestBodyJson != null) {
            pramsJson.putAll(requestBodyJson);
        }
        if (requestParamJson != null) {
            pramsJson.putAll(requestParamJson);
        }
        return pramsJson.toJSONString();
    }

    /**
     * url 参数转 JSONObject
     *
     * @param requestParams url 参数
     * @return JSONObject
     */
    private JSONObject getJsonObjectByQueryUrl(String requestParams) {
        String[] params = requestParams.split("&");
        JSONObject obj = new JSONObject();
        for (int i = 0; i < params.length; i++) {
            String[] param = params[i].split("=");
            if (param.length >= 2) {
                String key = param[0];
                String value = param[1];
                for (int j = 2; j < param.length; j++) {
                    value += "=" + param[j];
                }
                try {
                    obj.put(key, value);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }
}
